#include "include/gudb.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main() {
    // Open database
    gudb* db = gudb_open("./test_db", GU_OPEN_CREATE, "admin", "admin");
    if (!db) {
        printf("Failed to open database\n");
        return 1;
    }
    
    // Begin transaction
    gudb_txn* txn = gudb_begin(db, GU_TXN_RC, "gudb");
    if (!txn) {
        printf("Failed to begin transaction\n");
        gudb_close(db);
        return 1;
    }
    
    result_t* result = NULL;
    
    printf("=== Testing Database Isolation ===\n");
    
    // Clean start - create fresh databases
    printf("\n1. Setting up test environment...\n");
    gudb_exec(txn, "DROP DATABASE IF EXISTS db1", NULL, &result);
    if (result) gudb_free_result(result);
    gudb_exec(txn, "DROP DATABASE IF EXISTS db2", NULL, &result);
    if (result) gudb_free_result(result);
    
    gudb_exec(txn, "CREATE DATABASE db1", NULL, &result);
    if (result) gudb_free_result(result);
    gudb_exec(txn, "CREATE DATABASE db2", NULL, &result);
    if (result) gudb_free_result(result);
    
    printf("Created databases db1 and db2\n");
    
    // Test 1: Default database tables
    printf("\n2. Current database (should be 'gudb')...\n");
    if (gudb_exec(txn, "SHOW TABLES", NULL, &result) == GU_OK) {
        printf("Tables in default database:\n");
        for (uint32_t i = 0; i < result->row_count; i++) {
            printf("  - %s\n", result->rows[i][0]);
        }
        if (result->row_count == 0) {
            printf("  (no tables)\n");
        }
        gudb_free_result(result);
    }
    
    // Test 2: Switch to db1 and create table
    printf("\n3. Switching to db1...\n");
    if (gudb_exec(txn, "USE db1", NULL, &result) == GU_OK) {
        printf("Successfully switched to db1\n");
        if (result) gudb_free_result(result);
        
        // Create table in db1
        if (gudb_exec(txn, "CREATE TABLE users (id INT, name VARCHAR(50))", NULL, &result) == GU_OK) {
            printf("Created table 'users' in db1\n");
            if (result) gudb_free_result(result);
        }
        
        // Show tables in db1
        if (gudb_exec(txn, "SHOW TABLES", NULL, &result) == GU_OK) {
            printf("Tables in db1:\n");
            for (uint32_t i = 0; i < result->row_count; i++) {
                printf("  - %s\n", result->rows[i][0]);
            }
            if (result->row_count == 0) {
                printf("  (no tables - THIS IS WRONG!)\n");
            }
            gudb_free_result(result);
        }
    }
    
    // Test 3: Switch to db2 and check isolation
    printf("\n4. Switching to db2...\n");
    if (gudb_exec(txn, "USE db2", NULL, &result) == GU_OK) {
        printf("Successfully switched to db2\n");
        if (result) gudb_free_result(result);
        
        // Show tables in db2 (should be empty)
        if (gudb_exec(txn, "SHOW TABLES", NULL, &result) == GU_OK) {
            printf("Tables in db2:\n");
            for (uint32_t i = 0; i < result->row_count; i++) {
                printf("  - %s (THIS IS WRONG - should not see db1 tables!)\n", result->rows[i][0]);
            }
            if (result->row_count == 0) {
                printf("  (no tables - isolation working correctly!)\n");
            }
            gudb_free_result(result);
        }
        
        // Create table in db2
        if (gudb_exec(txn, "CREATE TABLE products (id INT, price FLOAT)", NULL, &result) == GU_OK) {
            printf("Created table 'products' in db2\n");
            if (result) gudb_free_result(result);
        }
        
        // Show tables in db2 again
        if (gudb_exec(txn, "SHOW TABLES", NULL, &result) == GU_OK) {
            printf("Tables in db2 after creating products:\n");
            for (uint32_t i = 0; i < result->row_count; i++) {
                printf("  - %s\n", result->rows[i][0]);
            }
            gudb_free_result(result);
        }
    }
    
    // Test 4: Switch back to db1 to verify isolation
    printf("\n5. Switching back to db1...\n");
    if (gudb_exec(txn, "USE db1", NULL, &result) == GU_OK) {
        printf("Back to db1\n");
        if (result) gudb_free_result(result);
        
        // Show tables in db1 (should only show 'users')
        if (gudb_exec(txn, "SHOW TABLES", NULL, &result) == GU_OK) {
            printf("Tables in db1 (should only show users):\n");
            for (uint32_t i = 0; i < result->row_count; i++) {
                if (strcmp(result->rows[i][0], "users") == 0) {
                    printf("  - %s (correct!)\n", result->rows[i][0]);
                } else {
                    printf("  - %s (WRONG - this table should not be visible from db1!)\n", result->rows[i][0]);
                }
            }
            if (result->row_count == 0) {
                printf("  (no tables - THIS IS WRONG, should show 'users'!)\n");
            }
            gudb_free_result(result);
        }
    }
    
    // Test 5: Try to drop table from wrong database
    printf("\n6. Testing cross-database table access...\n");
    printf("Currently in db1, trying to drop 'products' table (which is in db2):\n");
    if (gudb_exec(txn, "DROP TABLE products", NULL, &result) == GU_OK) {
        printf("ERROR: Successfully dropped 'products' - this should have failed!\n");
        if (result) gudb_free_result(result);
    } else {
        printf("Good: Failed to drop 'products' (table not found in current database)\n");
    }
    
    // Commit and cleanup
    gudb_commit(txn);
    gudb_close(db);
    
    printf("\n=== Test completed ===\n");
    return 0;
}